
var MENU = 0;
var PLAYING = 1;
var ENDING = 2;

var renderer, scene, camera;
var pointLight, spotLight;

var paddle1, paddle2, ball, wall, wallside1, wallside2;
var ballDirX = 1, ballDirY = 1, ballSpeed = 2;

// field variables
var fieldWidth = 400, fieldHeight = 200;

// paddle variables
var paddleWidth, paddleHeight, paddleDepth, paddleQuality;
var paddle1DirY = 0, paddle2DirY = 0, paddleSpeed = 3;

var difficulty = 0.15;
var state = ENDING;

var playerScore = 0;
var enemyScore = 0;

var level = 1;
var context;

function setup(){
    state = ENDING;
    createScene();

    draw();
}

function replayClick(){
    document.getElementById("loseMenu").style.display = "none";
    state = PLAYING;

    reset() ;
    level = 1;
    document.getElementById("scores").innerText = "Let's start level " + level + "!";
}

function backgameClick(){
    document.getElementById("logo").style.display = "block";
    document.getElementById("menu").style.display = "block";

    document.getElementById("gameCanvas").style.display = "none";
    document.getElementById("loseMenu").style.display = "none";

    reset() ;
    level = 1;
}

function newgameClick(){
    document.getElementById("logo").style.display = "none";
    document.getElementById("menu").style.display = "none";

    document.getElementById("gameCanvas").style.display = "block";
    state = PLAYING;
}

function createScene(){
    var WIDTH = 640,
        HEIGHT = 360;
    var VIEW_ANGLE = 50,
        ASPECT = WIDTH / HEIGHT,
        NEAR = 0.1,
        FAR = 10000;

    //create renderer
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(WIDTH, HEIGHT);

    var c = document.getElementById("gameCanvas");

    //camera
    camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);

    //scene
    scene = new THREE.Scene();
    scene.add(camera);

    camera.position.z = 320;

    c.appendChild(renderer.domElement);

    createBall();
    createPlayArea();
    createPaddles();
	//Tạo tường phía đằng sau
	createWall();
	//Tao tuong chan 2 ben
	createSideWall();
    createLights();

    createText();

    renderer.shadowMapEnabled = true;
}

function createText(){
    var paper = Raphael(0,0,400, 400)
    var path1 = helvetica['C'];
    var path2 = helvetica['U'];
    var path3 = helvetica['B'];
    var path4 = helvetica['E'];
    var path5 = helvetica['S'];
    var path6 = helvetica['L'];
    var path7 = helvetica['A'];
    var path8 = helvetica['M'];
    var anim = Raphael.animation({"13%": {path: path2,fill: "red", stroke: "yellow"},
        "26%": {path: path3,fill: "yellow", stroke: "black",fill: "#fff", stroke: "#fffa", "fill-opacity": .3, "stroke-width": 1, "stroke-linecap": "round", translation: "100 100"},
        "39%": {path: path4,fill: "black", stroke: "blue"},
        "52%": {path: path5,fill: "blue", stroke: "violet"},
        "65%": {path: path6,fill: "violet", stroke: "orange"},
        "77%": {path: path7,fill: "orange", stroke: "cyan"},
        "90%": {path: path8,fill: "cyan", stroke: "yellow"},
        "100%": {path: path1,fill: "yellow", stroke: "red"}},14000);
    var path = paper.path(path1).attr({fill: "orange", "stroke-width": 1});
    path.click(function(){
        path.animate(anim.repeat(2))
    });

    context = document.getElementById("detailCanvas").getContext('2d');

    context.beginPath();
    context.fillStyle = "blue";
    context.font = "bold 16px Arial";
    context.fillText("Enemy: ", 80, 20);

    context.fillStyle = "red";
    context.font = "bold 16px Arial";
    context.fillText("You: ", 80, 100);


    for(var i = 0; i < 3; i++){
        context.lineWidth = 2;
        context.fillStyle = "rgb(255, 255, 255)";
        context.fillRect(100 + i * 50, 30, 30, 30);
        context.strokeStyle = 'black';
        context.stroke();

        context.lineWidth = 2;
        context.fillRect(100 + i * 50, 110, 30, 30);
        context.strokeStyle = 'black';
        context.stroke();
    }
}

function createPlayArea(){
    var planeWidth = fieldWidth,
        planeHeight = fieldHeight,
        planeQuality = 10;

    var planeMaterial = new THREE.MeshLambertMaterial({
        color: 0x4BD121
    });

    var plane = new THREE.Mesh(
        new THREE.PlaneGeometry(
            planeWidth * 0.95,
            planeHeight,
            planeQuality,
            planeQuality
        ),
        planeMaterial
    );

    scene.add(plane);
    plane.receiveShadow = true;

    // create the table's material
    var tableMaterial =
        new THREE.MeshLambertMaterial(
            {
                color: 0x111111
            });

    var table = new THREE.Mesh(
        new THREE.CubeGeometry(
            planeWidth * 1.05,
            planeHeight * 1.03,
            100,
            planeQuality,
            planeQuality,
            1
        ),
        tableMaterial
    );
    table.position.z = -51;
    scene.add(table);
    table.receiveShadow = true;
}
//Tạo bức tường 2 bên
function createSideWall(){
	//material 3D
	var texture = THREE.ImageUtils.loadTexture( "textures/bg.jpg" );
	texture.wrapS = THREE.RepeatWrapping;
	texture.wrapT = THREE.RepeatWrapping;
	texture.repeat.set( 4, 4 );
	var wallMaterial =
        new THREE.MeshLambertMaterial(
            {
                color: 0x92E5F7
				//,map: texture
            });

    //Bức tường bên trái
    wallside1 = new THREE.Mesh(
        new THREE.CubeGeometry(
            870,
            4,
            100,
            1,
            1,
            1
        ),
        wallMaterial
    );
	scene.add(wallside1);
    //wallside1.receiveShadow = true;
    //wallside1.castShadow = true;
	wallside1.position.x = -200;
	wallside1.position.y = 110;
	wallside1.position.z = -1;
	//bức tường bên ơphai
	wallside2 = new THREE.Mesh(
        new THREE.CubeGeometry(
            870,
            4,
            100,
            1,
            1,
            1
        ),
        wallMaterial
    );
	wallside2.side = THREE.BackSide;
	scene.add(wallside2);
    //wallside2.receiveShadow = true;
    //wallside2.castShadow = true;
	wallside2.position.x = -200;
	wallside2.position.y = -110;
	wallside2.position.z = -1;
}

//Tạo bức tường đằng sau
function createWall(){

    var wallMaterial =
        new THREE.MeshLambertMaterial(
            {
                color: 0x1B52C3
            });

    //create paddle1
    wall = new THREE.Mesh(
        new THREE.CubeGeometry(
            4,
            200,
            100,
            1,
            1,
            1
        ),
        wallMaterial
    );
	scene.add(wall);
    wall.receiveShadow = true;
    wall.castShadow = true;
	wall.position.x = 200;
	wall.position.z = -1;
}

function createBall(){

    var radius = 5,
        segments = 6,
        rings = 6;

    var ballMaterial = new THREE.MeshLambertMaterial({
        color: 0xD43001
    });

    ball = new THREE.Mesh(
        new THREE.SphereGeometry(
            radius,
            segments,
            rings
        ),
        ballMaterial
    );

    scene.add(ball);
    ball.position.x = 0;
    ball.position.y = 0;
    ball.position.z = radius;
    ball.receiveShadow = true;
    ball.castShadow = true;
}

function createLights(){
    // create a point light
    pointLight = new THREE.PointLight(0xF8D898);
    pointLight.position.x = -1000;
    pointLight.position.y = 0;
    pointLight.position.z = 1000;
    pointLight.intensity = 2.9;
    pointLight.distance = 10000;
    scene.add(pointLight);

    // create a spot light
    spotLight = new THREE.SpotLight(0xF8D898);
    spotLight.position.set(0, 0, 460);
    spotLight.intensity = 1.5;
    spotLight.castShadow = true;
    scene.add(spotLight);
}

function createPaddles(){
    // set up the paddle vars
    paddleWidth = 10;
    paddleHeight = 30;
    paddleDepth = 10;
    paddleQuality = 1;

    var paddle1Material =
        new THREE.MeshLambertMaterial(
            {
                color: 0x1B32C0
            });
    // create the paddle2's material
    var paddle2Material =
        new THREE.MeshLambertMaterial(
            {
                color: 0xFF4045
            });

    //create paddle1
    paddle1 = new THREE.Mesh(
        new THREE.CubeGeometry(
            paddleWidth,
            paddleHeight,
            paddleDepth,
            paddleQuality,
            paddleQuality,
            paddleQuality
        ),
        paddle1Material
    );
    scene.add(paddle1);
    paddle1.receiveShadow = true;
    paddle1.castShadow = true;
    paddle1.position.x = - fieldWidth/2 + paddleWidth;
    paddle1.position.z = paddleDepth;

    paddle2 = new THREE.Mesh(
        new THREE.CubeGeometry(
            paddleWidth,
            paddleHeight,
            paddleDepth,
            paddleQuality,
            paddleQuality,
            paddleQuality
        ),
        paddle2Material
    );
    scene.add(paddle2);
    paddle2.receiveShadow = true;
    paddle2.castShadow = true;
    paddle2.position.x = fieldWidth/2 - paddleWidth;
    paddle2.position.z = paddleDepth;
}

function draw(){
    //draw three js scene
    renderer.render(scene, camera);

    //loop the draw function
    requestAnimationFrame(draw);
    renderCamera();

    //process game logic
    if(state == PLAYING){

        handleInput();
        updateEnemy();
        updateBall();
        paddleCollideWithBall(paddle1);
    }else if(state == MENU){
        if(Key.isDown(Key.SPACE))
        {
            state = PLAYING;
            ballDirY = 1;
            document.getElementById("scores").innerText = "Let's start level " + level + "!";
        }
    }

}

function renderCamera(){
    spotLight.position.x = ball.position.x * 2;
    spotLight.position.y = ball.position.y * 2;

    camera.position.x = paddle1.position.x -100;
    //camera.position.y += (paddle1.position.y - camera.position.y) * 0.05;
    camera.position.z = paddle1.position.z + 100 + 0.04 * ( paddle1.position.x);

    //camera.rotation.x = -0.01 * (ball.position.y) * Math.PI/180;
    camera.rotation.y = -60 * Math.PI/180;
    camera.rotation.z = -90 * Math.PI/180;
}

function handleInput(){
    if(Key.isDown(Key.LEFT)){
        if(paddle1.position.y < fieldHeight * 0.45){
            paddle1DirY = paddleSpeed;
        }else{
            paddle1DirY = 0;
            paddle1.scale.z += (10 - paddle1.scale.z) * 0.2;
        }
    }
    else if(Key.isDown(Key.RIGHT)){
        if(paddle1.position.y > -fieldHeight * 0.45){
            paddle1DirY = - paddleSpeed;
        }
        else{
            paddle1DirY = 0;
            paddle1.scale.z += (10 - paddle1.scale.z) * 0.2;
        }
    }
    else{
        paddle1DirY = 0;
    }

    paddle1.scale.y += (1 - paddle1.scale.y) * 0.2;
    paddle1.scale.z += (1 - paddle1.scale.z) * 0.2;
    paddle1.position.y += paddle1DirY;
}

function updateEnemy(){
    paddle2DirY = (ball.position.y - paddle2.position.y) * difficulty;

    if(Math.abs(paddle2DirY) <= paddleSpeed){
        paddle2.position.y += paddle2DirY;
    }else{
        if(paddle2DirY > paddleSpeed){
            paddle2.position.y += paddleSpeed;
        }else{
            paddle2.position.y -= paddleSpeed;
        }
    }
    paddle2.scale.y += (1 - paddle2.scale.y) * 0.2;

}

function updateBall(){

    if(ball.position.x <= -fieldWidth/2){
		Sounds.hit.play();
        ballDirX = -ballDirX;
    }

    if(ball.position.x >= fieldWidth/2){
		Sounds.hit.play();
        if(ball.position.y >= paddle2.position.y + paddleHeight/2 ||
            ball.position.y <= paddle2.position.y - paddleHeight/2){

            playerScore++;
            state = MENU;
            ball.position.x = 0;
            ball.position.y = 0;

            for(var i = 0; i < playerScore; i++){
                context.lineWidth = 2;
                context.fillStyle='green';
                context.fillRect(100 + i * 50, 110, 30, 30);
                context.strokeStyle = 'black';
                context.stroke();
            }

            if(playerScore >= 3){
                difficulty += 0.05;
                document.getElementById("scores").innerText = "You win!";
                reset();
            }
        }

        ballDirX = - ballDirX;
    }

    if(ball.position.y <= -fieldHeight/2){
		Sounds.hit.play();
        ballDirY = -ballDirY;
    }
    if(ball.position.y >= fieldHeight/2){
		Sounds.hit.play();
        ballDirY = - ballDirY;
    }
    ball.position.x += ballDirX * ballSpeed;
    ball.position.y += ballDirY * ballSpeed;

    if(ballDirY > ballSpeed * 1.5){
        ballDirY = ballSpeed * 1.5;
    }else if(ballDirY < -ballSpeed * 1.5){
        ballDirY = -ballSpeed * 1.5;
    }
}

function reset(){
    playerScore = 0;
    enemyScore = 0;
    level++;
	for(var i = 0; i < 3; i++){
        context.fillStyle = "rgb(255, 255, 255)";
        context.fillRect(100 + i * 50, 30, 30, 30);
        context.strokeStyle = 'black';
        context.lineWidth = 2;
        context.stroke();

			
        context.fillRect(100 + i * 50, 110, 30, 30);
        context.lineWidth = 2;
        context.strokeStyle = 'black';
        context.stroke();
    }
}
    


function paddleCollideWithBall(paddle){
    if(ball.position.x <= paddle.position.x + paddleWidth
        && ball.position.x >= paddle.position.x){

        if(ball.position.y <= paddle.position.y + paddleHeight/2
            && ball.position.y >= paddle.position.y - paddleHeight/2){

            if(ballDirX < 0){
                paddle.scale.y = 5;
			Sounds.hit.play();
                ballDirX = -ballDirX;

                ballDirY -= paddle1DirY * 0.7;
            }
        }
    }
    else
    {
        if(ball.position.x <= -fieldWidth/2)
        {
            enemyScore++;
            updateScore();
            state = MENU;
            ball.position.x = 0;
            ball.position.y = 0;
            if(enemyScore >= 3){
                state = ENDING;
                document.getElementById("scores").innerText = "You lose!";
                document.getElementById("loseMenu").style.display= "block";
            }
        }
    }
}



function updateScore(){
    for(var i = 0; i < enemyScore; i++){
        context.fillStyle='yellow';
        context.fillRect(100 + i * 50, 30, 30, 30);
        context.lineWidth = 2;
        context.strokeStyle = 'black';
        context.stroke();
    }
}

